//---------------------------------------------------------------------
// File: ReceiveLocationEnabledStep.cs
// 
// Summary: 
//---------------------------------------------------------------------
using System;
using System.Xml;
using System.Management;
using Microsoft.Services.BizTalkApplicationFramework.BizUnit;
namespace BizUnit.Extensions.BizTalk
{
    /// <summary>
	/// The SendPortStatusStep test step checks to determine whether a specific send port is started or stopped.
	/// </summary>
	/// 
	/// <remarks>
	/// The following shows an example of the Xml representation of this test step.
	/// 
	/// <code escaped="true">
    ///	<TestStep assemblyPath="BizUnitExtensions.BizTalk.dll" typeName="BizUnit.Extensions.BizTalk.SendPortStatusStep">
    ///		<SendPortName>GovenorIn</SendPortName>
    ///		<Status>Started</Status>
	///	</TestStep>
	///	</code>
	///	
	///	<list type="table">
	///		<listheader>
	///			<term>Tag</term>
	///			<description>Description</description>
	///		</listheader>
	///		<item>
	///			<term>SendPortNme</term>
	///			<description>The name of the send port to check</description>
	///		</item>
	///		<item>
    ///			<term>Status</term>
	///			<description>Check if it is Bound,Started,Stopped</description>
	///		</item>
	///	</list>
	///	</remarks>

    public class SendPortStatusStep : ITestStep
	{
		/// <summary>
		/// ITestStep.Execute() implementation
		/// </summary>
		/// <param name='testConfig'>The Xml fragment containing the configuration for this test step</param>
		/// <param name='context'>The context for the test, this holds state that is passed beteen tests</param>
		public void Execute(XmlNode testConfig, Context context)
		{
			string sendPortName = context.ReadConfigAsString( testConfig, "SendPortName" );
            string statusToCheck= context.ReadConfigAsString(testConfig, "Status");
		    string actualStatus = CheckSendPortStatus(sendPortName, context);

            if (!statusToCheck.Equals(actualStatus))
			{
			    throw new ApplicationException(
			        string.Format(
			            "The send port: {0} was expected to be in the status:{1} but was found to be in the status : {2} ",
			            sendPortName, statusToCheck, actualStatus));
			}
			else
			{
			    context.LogInfo(string.Format("The send port: {0} was found to be in the state {1}", sendPortName, actualStatus));
			}
		}

        private ManagementObject GetSendPortWmiObject(string sendPortName)
		{
			ManagementObjectSearcher searcher = new ManagementObjectSearcher();
			ManagementScope scope = new ManagementScope("root\\MicrosoftBizTalkServer");
			searcher.Scope = scope;
		
			// Build a Query to enumerate the MSBTS_SendPort instances if an argument
			// is supplied use it to select only the matching RL.
			SelectQuery query = new SelectQuery();
            query.QueryString = String.Format("SELECT * FROM MSBTS_SendPort WHERE Name =\"{0}\"", sendPortName);

			// Set the query for the searcher.
			searcher.Query = query;

			
			// Execute the query and determine if any results were obtained.
			ManagementObjectCollection queryCol = searcher.Get();
			
			ManagementObjectCollection.ManagementObjectEnumerator me = queryCol.GetEnumerator();
			me.Reset();
			if ( me.MoveNext() )
			{
				return (ManagementObject)me.Current;
			}
			else
			{
				throw new ApplicationException(string.Format("The WMI object for the send port:{0} could not be retrieved.", sendPortName ));
			}
		}

        private string CheckSendPortStatus(string sendPortName,Context context)
        {
            ManagementObject mo = GetSendPortWmiObject(sendPortName);
            string returnStatus;


            using (mo)
            {
                UInt32 moStatus = (UInt32) mo.GetPropertyValue("Status");
                //WMI SendPOrt status values are 1=bound 3=started 2=stopped
                switch (moStatus)
                {
                    case 1:
                        returnStatus = "Bound";
                        break;

                    case 2:
                        returnStatus = "Stopped";
                        break;

                    case 3:
                        returnStatus = "Started";
                        break;

                    default:
                        returnStatus = "Unknown";
                        context.LogWarning("status of send port is UNKNOWN");
                        break;
                }
            }


            return returnStatus;

        }
        
	
	}
}
